from django.db import models
from cmdb.models import Host
import json


class HostMetrics(models.Model):
    """主机监控指标模型"""
    host = models.ForeignKey(Host, on_delete=models.CASCADE, related_name='metrics', verbose_name='主机')

    # CPU指标
    cpu_usage = models.FloatField(verbose_name='CPU使用率(%)')
    cpu_load_1m = models.FloatField(verbose_name='1分钟负载')
    cpu_load_5m = models.FloatField(verbose_name='5分钟负载')
    cpu_load_15m = models.FloatField(verbose_name='15分钟负载')

    # 内存指标
    memory_total = models.BigIntegerField(verbose_name='总内存(bytes)')
    memory_used = models.BigIntegerField(verbose_name='已用内存(bytes)')
    memory_free = models.BigIntegerField(verbose_name='空闲内存(bytes)')
    memory_usage = models.FloatField(verbose_name='内存使用率(%)')

    # 磁盘指标
    disk_total = models.BigIntegerField(verbose_name='总磁盘(bytes)')
    disk_used = models.BigIntegerField(verbose_name='已用磁盘(bytes)')
    disk_free = models.BigIntegerField(verbose_name='空闲磁盘(bytes)')
    disk_usage = models.FloatField(verbose_name='磁盘使用率(%)')

    # 网络指标
    network_bytes_sent = models.BigIntegerField(verbose_name='网络发送(bytes)')
    network_bytes_recv = models.BigIntegerField(verbose_name='网络接收(bytes)')
    network_packets_sent = models.BigIntegerField(verbose_name='发送包数')
    network_packets_recv = models.BigIntegerField(verbose_name='接收包数')

    # 进程信息
    process_count = models.IntegerField(verbose_name='进程数')
    zombie_process_count = models.IntegerField(default=0, verbose_name='僵尸进程数')

    # 系统信息
    uptime = models.BigIntegerField(verbose_name='运行时间(秒)')
    boot_time = models.DateTimeField(verbose_name='启动时间')

    # 采集时间
    collected_at = models.DateTimeField(auto_now_add=True, verbose_name='采集时间', db_index=True)

    class Meta:
        db_table = 'monitoring_host_metrics'
        verbose_name = '主机监控指标'
        verbose_name_plural = '主机监控指标'
        ordering = ['-collected_at']
        indexes = [
            models.Index(fields=['host', '-collected_at']),
            models.Index(fields=['collected_at']),
        ]

    def __str__(self):
        return f"{self.host.hostname} - {self.collected_at}"

    @property
    def memory_usage_gb(self):
        """内存使用量(GB)"""
        return round(self.memory_used / (1024**3), 2)

    @property
    def disk_usage_gb(self):
        """磁盘使用量(GB)"""
        return round(self.disk_used / (1024**3), 2)


class ProcessInfo(models.Model):
    """进程信息模型"""
    host = models.ForeignKey(Host, on_delete=models.CASCADE, related_name='processes', verbose_name='主机')
    pid = models.IntegerField(verbose_name='进程ID')
    name = models.CharField(max_length=255, verbose_name='进程名')
    cmdline = models.TextField(verbose_name='命令行')
    cpu_percent = models.FloatField(verbose_name='CPU使用率(%)')
    memory_percent = models.FloatField(verbose_name='内存使用率(%)')
    memory_rss = models.BigIntegerField(verbose_name='物理内存(bytes)')
    memory_vms = models.BigIntegerField(verbose_name='虚拟内存(bytes)')
    status = models.CharField(max_length=20, verbose_name='状态')
    create_time = models.DateTimeField(verbose_name='创建时间')
    collected_at = models.DateTimeField(auto_now_add=True, verbose_name='采集时间', db_index=True)

    class Meta:
        db_table = 'monitoring_process_info'
        verbose_name = '进程信息'
        verbose_name_plural = '进程信息'
        ordering = ['-cpu_percent']
        indexes = [
            models.Index(fields=['host', '-collected_at']),
            models.Index(fields=['collected_at']),
        ]

    def __str__(self):
        return f"{self.host.hostname} - {self.name} ({self.pid})"


class ServiceStatus(models.Model):
    """服务状态模型"""
    host = models.ForeignKey(Host, on_delete=models.CASCADE, related_name='services', verbose_name='主机')
    service_name = models.CharField(max_length=100, verbose_name='服务名')
    status = models.CharField(max_length=20, verbose_name='状态', choices=[
        ('running', '运行中'),
        ('stopped', '已停止'),
        ('failed', '失败'),
        ('unknown', '未知')
    ])
    pid = models.IntegerField(null=True, blank=True, verbose_name='进程ID')
    port = models.IntegerField(null=True, blank=True, verbose_name='端口')
    config_path = models.CharField(max_length=500, blank=True, null=True, verbose_name='配置文件路径')
    log_path = models.CharField(max_length=500, blank=True, null=True, verbose_name='日志文件路径')
    collected_at = models.DateTimeField(auto_now_add=True, verbose_name='采集时间', db_index=True)

    class Meta:
        db_table = 'monitoring_service_status'
        verbose_name = '服务状态'
        verbose_name_plural = '服务状态'
        ordering = ['-collected_at']
        unique_together = ['host', 'service_name', 'collected_at']
        indexes = [
            models.Index(fields=['host', 'service_name', '-collected_at']),
            models.Index(fields=['collected_at']),
        ]

    def __str__(self):
        return f"{self.host.hostname} - {self.service_name}"


class AlertRule(models.Model):
    """告警规则模型"""
    name = models.CharField(max_length=100, verbose_name='规则名称')
    metric_type = models.CharField(max_length=50, verbose_name='指标类型', choices=[
        ('cpu_usage', 'CPU使用率'),
        ('memory_usage', '内存使用率'),
        ('disk_usage', '磁盘使用率'),
        ('load_average', '系统负载'),
        ('process_count', '进程数'),
        ('service_status', '服务状态')
    ])
    operator = models.CharField(max_length=10, verbose_name='操作符', choices=[
        ('>', '大于'),
        ('>=', '大于等于'),
        ('<', '小于'),
        ('<=', '小于等于'),
        ('==', '等于'),
        ('!=', '不等于')
    ])
    threshold = models.FloatField(verbose_name='阈值')
    duration = models.IntegerField(default=300, verbose_name='持续时间(秒)')
    severity = models.CharField(max_length=20, default='warning', verbose_name='严重级别', choices=[
        ('info', '信息'),
        ('warning', '警告'),
        ('critical', '严重')
    ])
    description = models.TextField(blank=True, null=True, verbose_name='描述')
    is_active = models.BooleanField(default=True, verbose_name='是否激活')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')

    class Meta:
        db_table = 'monitoring_alert_rule'
        verbose_name = '告警规则'
        verbose_name_plural = '告警规则'
        ordering = ['-created_at']

    def __str__(self):
        return self.name
